<script setup lang="tsx">
import { SelectedItem, useTableDialogStore } from '@/store/modules/tableDialog'
import { ref, defineProps, unref, watch, nextTick } from 'vue'
import { Dialog } from '@/components/Dialog'
import { useI18n } from '@/hooks/web/useI18n'
import { useTable } from '@/hooks/web/useTable'
import { Search } from '@/components/Search'
import { Table } from '@/components/Table'
import { CurdData } from '@/api/customer/types'
import { ElMessage } from 'element-plus'

// 定义组件的 props
const props = defineProps({
  tableDialogStoreID: {
    type: String,
    required: true
  },
  limit: {
    type: Number,
    default: 1
  },
  getListApi: {
    type: Function,
    required: true
  },
  // 表格中显示的标题名称
  itemTitleName: {
    type: String,
    required: true
  },
  apiParams: {
    type: Object,
    default: () => ({})
  },
  // 是否多选，不限制数量
  isMultiple: {
    type: Boolean,
    default: false
  },
  rowKey: {
    type: String,
    default: ''
  },
  reserveSelection: {
    type: Boolean,
    default: false
  }
})

const { t } = useI18n()
const tableDialogStore = useTableDialogStore(props.tableDialogStoreID)

const searchParams = ref({})
// 设置搜索参数并调用获取列表的方法
const setSearchParams = (params: any) => {
  currentPage.value = 1
  searchParams.value = params
  nextTick(() => {
    getList()
  })
}
const { tableRegister, tableState, tableMethods } = useTable({
  fetchDataApi: async () => {
    const { currentPage, pageSize } = tableState

    const res = await props.getListApi({
      pageIndex: unref(currentPage),
      pageSize: unref(pageSize),
      ...unref(searchParams),
      ...(props.apiParams || {})
    })

    return {
      list: res.data.list,
      total: res.data.total
    }
  }
})

const { loading, dataList, total, currentPage, pageSize } = tableState
const { getList, getElTableExpose } = tableMethods

const selectedItems = ref<SelectedItem[]>([])

const additional = ref<any>([])

// 选择数据行
const selectData = async (row: CurdData | null) => {
  const elTableExpose = await getElTableExpose()
  const selection = row ? [row] : elTableExpose?.getSelectionRows() || []

  additional.value = selection

  if (selection.length > props.limit && !props.isMultiple) {
    ElMessage.error(`选中数据不能选择超过 ${props.limit} 条。`)
    return
  }

  if (selection.length === 0) {
    ElMessage.error('请至少选择一条数据。')
    return
  }

  selectedItems.value = selection.map((v: CurdData) => ({
    id: v.id,
    title: v[props.itemTitleName]
  }))
  tableDialogStore.selectedItems = selectedItems.value
  tableDialogStore.closeDialog()
}

// 设置默认选中的行
const setDefaultSelectedRows = async () => {
  const elTableRef = await getElTableExpose()

  if (elTableRef && tableDialogStore.selectedItems.length) {
    elTableRef.clearSelection()
    tableDialogStore.selectedItems.forEach((item) => {
      nextTick(() => {
        elTableRef.toggleRowSelection(item, true)
      })
    })
  }
}

// 监听对话框可见性变化
const currentKey = ref('')
watch(
  () => tableDialogStore.isTableDialogVisible,
  (newVal) => {
    if (newVal) {
      currentKey.value = props.tableDialogStoreID + new Date().getTime()
      nextTick(() => {
        getList()
        setDefaultSelectedRows()
      })
    }
  }
)

const emit = defineEmits<{
  (event: 'submit', selectData: any): void
  (event: 'additional', selectData: any): void
}>()

// 表单提交方法
const formSubmit = async () => {
  await selectData(null)
  emit('submit', tableDialogStore.selectedItems)
  emit('additional', additional.value)
}
</script>

<template>
  <Dialog
    :key="currentKey"
    width="80%"
    maxHeight="60vh"
    v-model="tableDialogStore.isTableDialogVisible"
    :title="t('dialogDemo.dialog')"
  >
    <div class="container">
      <Search
        :schema="tableDialogStore.schema.searchSchema"
        @search="setSearchParams"
        @reset="setSearchParams"
      />

      <Table
        v-model:pageSize="pageSize"
        v-model:currentPage="currentPage"
        showAction
        :columns="tableDialogStore.schema.tableColumns"
        :data="dataList"
        :loading="loading"
        :row-key="props.rowKey || 'id'"
        :reserveSelection="props.reserveSelection"
        :pagination="{
          total: total
        }"
        @register="tableRegister"
      />
    </div>
    <template #footer>
      <BaseButton type="primary" @click="formSubmit">{{ t('dialogDemo.submit') }}</BaseButton>
      <BaseButton @click="tableDialogStore.closeDialog">{{ t('dialogDemo.close') }}</BaseButton>
    </template>
  </Dialog>
</template>

<style scoped>
.container {
  width: 98%;
  padding: 10px 10px 20px;
  margin-right: 10px;
  overflow: auto;
}
</style>
